package com.scs.application.modules.base.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scs.application.core.dto.ExcelImportField;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.PinYinUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.base.dto.SpChangeNameDTO;
import com.scs.application.modules.base.dto.SupplierToMscmDTO;
import com.scs.application.modules.base.entity.Supplier;
import com.scs.application.modules.base.mapper.SupplierMapper;
import com.scs.application.modules.base.service.MatrService;
import com.scs.application.modules.base.service.SupplierService;
import com.scs.application.modules.sys.entity.*;
import com.scs.application.modules.sys.mapper.ScheduleJobMapper;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.service.ScheduleJobService;
import com.scs.application.modules.thirdparty.dto.SupplierDTO;
import com.scs.application.modules.thirdparty.service.MscmService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Slf4j
@Service
public class SupplierServiceImpl extends BaseServiceImpl<SupplierMapper, Supplier> implements SupplierService {
    @Autowired
    private MscmService mscmService;

    @Autowired
    @Lazy
    private ScheduleJobService scheduleJobService;


    @Autowired
    @Lazy
    MatrService matrService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public String syncSupplierFromMscm() {
        // MSCM系统中供应商数据
        List<SupplierDTO> dtos = mscmService.getSupplierList();
        log.info("供应商系统同步供应商,数量{}", dtos.size());
        if (dtos.isEmpty()) {
            return "供应商系统同步供应商,数量0";
        }
        List<Supplier> suppliers = this.list(Wrappers.<Supplier>query().select("*"));
        Map<String, Supplier> supplierMap = suppliers.stream().collect(Collectors.toMap(o -> o.getName(), o -> o, (o1, o2) -> o1));
        List<Supplier> updateSuppliers = Lists.newArrayListWithCapacity(dtos.size());
        List<Supplier> insertSuppliers = Lists.newArrayListWithCapacity(dtos.size());
        for (SupplierDTO dto : dtos) {
            Supplier supplier = supplierMap.get(dto.getName());

            //如果供应商存在，更新
            if (supplier != null) {
                supplier.setId(supplier.getId());
                supplier.setName(dto.getName()).setMscmCode(dto.getId())
                        .setContacts(dto.getContacts()).setTelephone(dto.getTelephone())
                        .setAddress(dto.getAddress()).setCompanyCode(dto.getCompanyCode());
                updateSuppliers.add(supplier);
            }else {
                supplier = new Supplier();
                supplier.setName(dto.getName()).setMscmCode(dto.getId())
                        .setContacts(dto.getContacts()).setTelephone(dto.getTelephone())
                        .setAddress(dto.getAddress()).setCompanyCode(dto.getCompanyCode());
                insertSuppliers.add(supplier);
            }
        }

        if (!updateSuppliers.isEmpty()) {
            this.updateBatchById(updateSuppliers);
        }
        if (!insertSuppliers.isEmpty()) {
            this.saveBatch(insertSuppliers);
        }

        log.info(StrUtil.format("供应商系统同步供应商,总数量{},新增{},更新{}",dtos.size(),insertSuppliers.size(),updateSuppliers.size()));
        return StrUtil.format("供应商系统同步供应商,总数量{},新增{},更新{}",dtos.size(),insertSuppliers.size(),updateSuppliers.size());
    }

    @Override
    public boolean saveOrUpdate(Supplier entity) {
        if (StringUtils.isBlank(entity.getDistributorId())) {
            entity.setDistributorId(null);
        }
        Supplier supplier = super.getOne(Wrappers.<Supplier>query()
                .eq("name", entity.getName())
                .ne(!entity.isNewRecord(), "id", entity.getId()));

        if (supplier != null) {
            throw new BusinessException("供应商名字【" + entity.getName() + "】已存在，请使用其他名称");
        }
        return super.saveOrUpdate(entity);
    }

    /**
     * 根据MSCMCode获取供应商信息
     *
     * @param mscmCode
     * @return
     */
    @Override
    public Supplier getSupplierByMscmCode(String mscmCode) {
        List<Supplier> supplierList = super.list(new QueryWrapper<Supplier>().eq("mscm_code", mscmCode));
        if (supplierList.isEmpty()) {
            return null;
        }
        return supplierList.get(0);
    }

    /**
     * 从hrp同步供应商
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public RestResult syncSupplierFromHrp(List<SupplierDTO> dtos) {
        List<Supplier> supplierList = this.list(Wrappers.<Supplier>query().select("id,hrp_code,name"));
        Map<String, Supplier> supplierMap = supplierList.stream().collect(Collectors.toMap(o -> o.getHrpCode(), o -> o, (o1, o2) -> o1));
        log.info("加载到{}条供应商数据", supplierMap.size());
        List<Supplier> insertSuppliers = Lists.newArrayListWithCapacity(dtos.size());
        List<Supplier> updateSuppliers = Lists.newArrayListWithCapacity(dtos.size());
        for (SupplierDTO dto : dtos) {
            Supplier s = supplierMap.get(dto.getCode());
            Supplier supplier = new Supplier();
            String pinyin = PinYinUtils.getAlpha(dto.getName());
            if (s != null) {
                supplier.setName(dto.getName()).setNamePy(StringUtils.substring(pinyin, 0, 10)).setHrpCode(dto.getCode()).setId(s.getId());
                updateSuppliers.add(supplier);
                //continue;
            } else {
                supplier.setName(dto.getName()).setNamePy(StringUtils.substring(pinyin, 0, 10)).setHrpCode(dto.getCode());
                insertSuppliers.add(supplier);
            }
        }

        if (!insertSuppliers.isEmpty()) {
            this.saveBatch(insertSuppliers);
        }
        if (!updateSuppliers.isEmpty()) {
            this.updateBatchById(updateSuppliers);
        }

        log.info("本次同步供应商{}个， 更新{}个，新增{}个", dtos.size(), updateSuppliers.size(), insertSuppliers.size());

        return RestResult.ok("同步成功，"+String.format("本次同步供应商%s个， 更新%s个，新增%s个",dtos.size(), updateSuppliers.size(), insertSuppliers.size()));
    }

    @Override
    public Page<Map> pageForSelect(QueryContext context, Map<String, Object> userParam) {
        return this.baseMapper.pageForSelect(context.getPage(), context.getWrapper(), context.getParams(),userParam);
    }



    public  String  supplierToMscm(){
        final int limit = 50;
        int total = 0;
        Date beginDate = null;
        // 取上次任务执行时间
        try {
            String strBeginDate = scheduleJobService.getLastSuccessDate("hisDeptServiceImpl.syncHisDept()");
            beginDate = DateUtils.parse(strBeginDate);
            List<SupplierToMscmDTO> supplierToMscmDTOS = baseMapper.getSupplierToMscm(beginDate);
            if (supplierToMscmDTOS.isEmpty()) {
                log.info("没有需要推送的供应商");
                return "没有需要推送的供应商";
            }
            log.info("本次推送供应商:{}个", supplierToMscmDTOS.size());

            for (int i = 0; i < supplierToMscmDTOS.size(); i += limit) {

                List<SupplierToMscmDTO> supplierToMscmDTOList = supplierToMscmDTOS.stream().skip(i).limit(limit).collect(Collectors.toList());
                ResponseEntity<RestResult> response = mscmService.supplierToMscm(strBeginDate,supplierToMscmDTOList);


                List<String> codeList = (List<String>) response.getBody().getData();
                if (supplierToMscmDTOList == null || supplierToMscmDTOList.size() == 0 || codeList == null || codeList.size() != supplierToMscmDTOList.size()) {
                    throw new BusinessException("推送供应商返回数据不正确，应返回：" + supplierToMscmDTOList.size() + "条数据，现只返回"
                            + codeList.size() + "条，返回报文如下：" + response);
                }
                for (int j = 0; j < supplierToMscmDTOList.size(); j++) {
                    if (!codeList.get(j).equalsIgnoreCase(supplierToMscmDTOList.get(j).getCode())) {
                        int num = baseMapper.update(null, Wrappers.<Supplier>update().set("mscm_code", codeList.get(j))
                                .eq("id", supplierToMscmDTOList.get(j).getSupplierId()));
                        total = num + total;
                    }
                }
            }
            log.info("本次推送供应商维护供应商为: {}个", supplierToMscmDTOS.size());
            return String.format("本次推送供应商:%s个",supplierToMscmDTOS.size());
        } catch (Exception e) {
            log.error("supplierToMscm.error",e);
            throw e;
        }
    }


    /**@Description： 导入模板字段标题
     */
    @Override
    protected List<ExcelImportField> excelGetFieldHead() {
        List<ExcelImportField> exportHeadList = new ArrayList<ExcelImportField>();
        ExcelImportField headDTO;

        headDTO = new ExcelImportField();
        headDTO.setName("name").setText("供应商名称").setCellIndex(0).setRequired(true).setMaxLength(150).setUnq(true);
        exportHeadList.add(headDTO);

        headDTO = new ExcelImportField();
        headDTO.setName("companyCode").setText("社会信用代码").setCellIndex(1).setRequired(false).setMaxLength(50).setUnq(true);
        exportHeadList.add(headDTO);

        headDTO = new ExcelImportField();
        headDTO.setName("remark").setText("备注").setCellIndex(2).setRequired(false).setMaxLength(300);
        exportHeadList.add(headDTO);
        return  exportHeadList;
    }


    // 导入数据 到数据库中
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String excelImportToDb(Map<String, String> reqData, List<Supplier> itemImportList) {

        // 名称分组
        Map<String,Supplier> groupByName = this.list(Wrappers.<Supplier>query())
                .stream().collect(Collectors.toMap(Supplier::getName, item -> item));
        ;

        // 新增
        List<Supplier> dataListAdd = new ArrayList<>();

        for(Supplier item  : itemImportList) {

            // 已存在
            if (!groupByName.containsKey(item.getName())) {
                item.setFlagDisabled(false)
                ;
                dataListAdd.add(item);
            }
        }

        if (!dataListAdd.isEmpty()) {
            this.saveBatch(dataListAdd);
        }

        return StrUtil.format("数据总量:{},新增数量:{}",itemImportList.size(),dataListAdd.size());
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public String changeName(SpChangeNameDTO changeParam) {
        Supplier supplier = new Supplier();
        supplier.setName(changeParam.getNameNew());
        supplier.setNamePy(PinYinUtils.getAlpha(changeParam.getNameNew()));

        String remark = StrUtil.format(
                "用户[{}] {} 变更供应商名称创建",
                UserUtils.currentUser().getName(),
                DateUtils.format(DateUtils.nowDate(DateUtils.YYYYMMDDHHMMSS_PATTER2),DateUtils.YYYYMMDDHHMMSS_PATTER2)
        );
        supplier.setRemark(remark);
        this.saveOrUpdate(supplier);
        if (changeParam.getFlagCopyMatr()) {
            return "操作成功，新增供应商1，" + matrService.copyMatrBySpNameChange(changeParam,supplier,remark);
        }
        return "操作成功，新增供应商1";
    }
}
